<template>
	<div class="login-container">
		<!-- 顶部 -->
		<div class="top-switch">
			<el-switch
				v-model="isDark"
				inline-prompt
				:active-icon="Moon"
				:inactive-icon="Sunny"
				active-color="var(--el-fill-color-dark)"
				inactive-color="var(--el-color-primary)"
				@change="handleThemeChange(isDark)"
			/>
			<lang-select class="lang-select" />
		</div>
		<!-- 登录表单 -->
		<el-card class="login-card">
			<div class="login-title">
				<h2>{{ title }}</h2>
				<el-tag class="version">{{ version }}</el-tag>
			</div>
			<el-form
				ref="loginFormRef"
				:model="loginData"
				:rules="loginRules"
				class="login-form"
			>
				<el-form-item prop="username">
					<div class="form-item">
						<svg-icon icon-class="user" class="mg2" />

						<el-input
							ref="username"
							v-model="loginData.username"
							class="form-input"
							size="large"
							:placeholder="$t('用户名')"
							name="username"
						/>
					</div>
				</el-form-item>

				<el-tooltip
					:disabled="!isCapslock"
					content="大写键已打开"
					placement="right"
				>
					<el-form-item prop="password">
						<div class="form-item">
							<svg-icon icon-class="password" class="mg2" />

							<el-input
								v-model="loginData.password"
								:placeholder="$t('密码')"
								:type="passwordVisible === false ? 'password' : 'input'"
								size="large"
								name="password"
								@keyup="checkCapslock"
								@keyup.enter="handleLogin"
								class="form-input"
							/>
							<span
								class="right-icon"
								@click="passwordVisible = !passwordVisible"
							>
								<svg-icon
									:icon-class="passwordVisible === false ? 'eye' : 'eye-open'"
								/>
							</span>
						</div>
					</el-form-item>
				</el-tooltip>

				<!-- 验证码 -->
				<el-form-item prop="captchaCode">
					<div class="form-item">
						<svg-icon icon-class="captcha" class="mg2" />
						<el-input
							v-model="loginData.captchaCode"
							auto-complete="off"
							:placeholder="$t('验证码')"
							class="form-input"
							@keyup.enter="handleLogin"
						/>

						<div class="captcha">
							<el-image :src="captchaBase64" @click="getCaptcha">
								<template #error>
									<div class="image-slot">
										<i-ep-picture />
									</div>
								</template>
							</el-image>
						</div>
					</div>
				</el-form-item>

				<el-button
					:loading="loading"
					type="primary"
					class="login-button"
					@click.prevent="handleLogin"
					>{{ $t("登陆") }}
				</el-button>
			</el-form>
		</el-card>

		<!-- ICP备案 -->
		<div class="login-bottom" v-show="useAppStore().device == 'desktop'">
			<p>
				Copyright © 2021 - 2023 youlai.tech All Rights Reserved. 有来技术
				版权所有
			</p>
			<p>皖ICP备20006496号-3</p>
		</div>
	</div>
</template>

<script setup lang="ts">
import { useI18n } from "vue-i18n";
import router from "@/router";
import LangSelect from "@/components/LangSelect/index.vue";
import SvgIcon from "@/components/SvgIcon/index.vue";
import { Moon, Sunny } from "@element-plus/icons-vue";

import { useSettingsStore } from "@/store/modules/settings";

// 状态管理依赖
import { useUserStore } from "@/store/modules/user";
import { useAppStore } from "@/store/modules/app";

// API依赖
import { LocationQuery, LocationQueryValue, useRoute } from "vue-router";
import { getCaptchaApi } from "@/api/auth";
import { LoginData } from "@/api/auth/types";

import config from "../../../package.json";

const settingsStore = useSettingsStore();

const { name: title, version } = config;

const isDark = ref<boolean>(settingsStore.theme === "dark");
/**
 * 明亮/暗黑主题切换
 * @param isDark
 */
const handleThemeChange = (isDark: boolean) => {
	useToggle(isDark);
	settingsStore.changeSetting("theme", isDark ? "dark" : "light");
};

/**
 * 根据屏幕宽度切换设备模式
 */
const appStore = useAppStore();
const WIDTH = 992; // 响应式布局容器固定宽度  大屏（>=1200px） 中屏（>=992px） 小屏（>=768px）
const { width } = useWindowSize();
watchEffect(() => {
	if (width.value < WIDTH) {
		appStore.toggleDevice("mobile");
	} else {
		appStore.toggleDevice("desktop");
	}
});

const loading = ref(false); // 按钮loading
const isCapslock = ref(false); // 是否大写锁定
const passwordVisible = ref(false); // 密码是否可见
const captchaBase64 = ref(); // 验证码图片Base64字符串
const loginFormRef = ref(ElForm); // 登录表单ref

const loginData = ref<LoginData>({
	username: "admin",
	password: "123456"
});

const { t } = useI18n();
const loginRules = computed(() => {
	const prefix = appStore.language === "en" ? "Please enter " : "请输入";
	return {
		username: [
			{
				required: true,
				trigger: "blur",
				message: `${prefix}${t("用户名")}`
			}
		],
		password: [
			{
				trigger: "blur",
				validator: (rule: any, value: any, callback: any) => {
					if (!value) {
						callback(ElMessage.error(`${prefix}${t("密码")}`));
					}
					if (value.length < 6) {
						callback(new Error("The password can not be less than 6 digits"));
					} else {
						callback();
					}
				},
				message: `${prefix}${t("密码")}`
			}
		],
		captchaCode: [
			{
				required: true,
				trigger: "blur",
				message: `${prefix}${t("验证码")}`
			}
		]
	};
});

/**
 * 检查输入大小写状态
 * @param e
 */
function checkCapslock(e: KeyboardEvent) {
	const { key } = e;
	isCapslock.value = (key &&
		key.length === 1 &&
		key >= "A" &&
		key <= "Z") as boolean;
}

/**
 * 获取验证码
 */
function getCaptcha() {
	getCaptchaApi().then(({ data }) => {
		loginData.value.captchaKey = data.captchaKey;
		captchaBase64.value = data.captchaBase64;
	});
}

const route = useRoute();
const userStore = useUserStore();
/**
 * 登录
 */
function handleLogin() {
	loginFormRef.value.validate((valid: boolean) => {
		if (valid) {
			loading.value = true;
			userStore
				.login(loginData.value)
				.then(() => {
					const query: LocationQuery = route.query;

					const redirect = (query.redirect as LocationQueryValue) ?? "/";

					const otherQueryParams = Object.keys(query).reduce(
						(acc: any, cur: string) => {
							if (cur !== "redirect") {
								acc[cur] = query[cur];
							}
							return acc;
						},
						{}
					);

					router.push({ path: redirect, query: otherQueryParams });
				})
				.catch(() => {
					// 验证失败，重新生成验证码
					getCaptcha();
				})
				.finally(() => {
					loading.value = false;
				});
		}
	});
}

onMounted(() => {
	getCaptcha();

	// 主题初始化
	const theme = useSettingsStore().theme;
	useSettingsStore().changeSetting("theme", theme);
	if (theme == "dark") {
		document.documentElement.classList.add("dark");
	} else {
		document.documentElement.classList.remove("dark");
	}
});
</script>

<style lang="scss" scoped>
.dark .login-container {
	background: url("@/assets/images/login-bg-dark.jpg") no-repeat center right;
}

.login-container {
	width: 100%;
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow-y: auto;
	background: url("@/assets/images/login-bg.jpg") no-repeat center right;
	.top-switch {
		display: flex;
		justify-content: flex-end;
		align-items: center;
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		padding: 0.75rem;
		.lang-select {
			margin-left: 0.5rem;
			cursor: pointer;
		}
	}
	.login-card {
		background-color: transparent;
		border-style: none;
		border-radius: 4%;
		width: 25rem;
	}
	.login-title {
		text-align: center;
		position: relative;
		.version {
			margin-left: 0.25rem;
			position: absolute;
			right: 0;
			top: 0;
		}
	}
	.login-form {
		padding: 30px 10px;

		.captcha {
			position: absolute;
			top: 0;
			right: 0;
			.el-image {
				height: 48px;
				flex: 1;
				cursor: pointer;
			}
			.image-slot {
				display: flex;
				align-items: center;
				justify-content: right;
				width: 100%;
				height: 100%;
				font-size: 18px;
				color: var(--el-text-color-secondary);
				background: var(--el-fill-color-light);

				svg {
					margin-right: 10px;
				}
			}
		}
		.login-button {
			width: 100%;
			margin-bottom: 30px;
		}
	}
	.form-item {
		display: flex;
		align-items: center;
		width: 100%;
		.mg2 {
			margin: 0 0.5rem;
		}
		.form-input {
			height: 48px;
			flex: 1;
		}
		.right-icon {
			margin-right: 0.5rem;
			cursor: pointer;
		}
	}
}

.el-form-item {
	background: var(--el-input-bg-color);
	border: 1px solid var(--el-border-color);
	border-radius: 5px;
}
.login-bottom {
	position: absolute;
	font-size: 10px;
	text-align: center;
	bottom: 0.25rem;
}

:deep(.el-input) {
	.el-input__wrapper {
		padding: 0;
		background-color: transparent;
		box-shadow: none;

		&.is-focus,
		&:hover {
			box-shadow: none !important;
		}

		input:-webkit-autofill {
			transition: background-color 1000s ease-in-out 0s; /* 通过延时渲染背景色变相去除背景颜色 */
		}
	}
}
</style>
